/*
-------------------------------------------------------------------
BIE is Copyright 2001-2003 Brunswick Corp.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/bie_license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
*/
package com.webdeninteractive.sbie.soap;

import com.webdeninteractive.sbie.ProtocolHandler;
import com.webdeninteractive.sbie.ServiceEndpoint;
import com.webdeninteractive.sbie.Client;
import com.webdeninteractive.sbie.Service;
import com.webdeninteractive.sbie.exception.TransportException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import java.net.URL;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;

import java.rmi.RemoteException;
import javax.xml.soap.SOAPException;
import javax.xml.rpc.ServiceException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConnection;
import javax.xml.transform.dom.DOMSource;

import org.apache.log4j.Logger;
import java.util.logging.Level;


/**
 * ProtocolHandler for sending SBIE messages via SOAP.
 *<P>
 * <B>Note:</B> This implementation is incomplete and nonfunctional.
 *
 * @author  mlee
 * @version $Id: SoapProtocolHandlerJAXM.java,v 1.1.1.1 2003/05/20 16:56:49 gdf Exp $ 
 */
public class SoapProtocolHandlerJAXM implements ProtocolHandler {

    private Logger logger = Logger.getLogger("com.webdeninteractive.sbie.soap.SoapProtocolHandlerJAXM");
    
    protected Client parent;

    public void setParentClient( Client parent ) {
        this.parent = parent;
    }

    public Client getParentClient() {
        return this.parent;
    }

    public ServiceEndpoint createServiceEndpoint( Service service ) {
        SoapServiceEndpoint ep = new SoapServiceEndpoint();
        // configure with service.getParameter(), if needed
        return ep;
    }

    /** Send a message via the implemented protocol.
     *  It's up to a Service calling this method to package and interpret
     *  the stream data.
     *  @param in Document containing data to send as message.
     *  @return Document containing response message.
     *  @throws ServiceException if a new SOAP service cannot be created (axis doesn't document why)
     *  @throws SOAPException if the errors occur in creating the SOAP message
     *  @throws RemoteException if the message cannot be sent
     */
    public Document sendMessage(ServiceEndpoint endpoint, Document in)
        throws TransportException
    {
        try {
            SoapServiceEndpoint sep = (SoapServiceEndpoint) endpoint;
            URL url = sep.getTargetEndpointAddress();
            String methodName = sep.getMethod();

            MessageFactory mf = MessageFactory.newInstance();
            SOAPMessage message = mf.createMessage();
            SOAPPart soapPart = message.getSOAPPart();

            // should wrap $in in:
/*
  <SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  <SOAP-ENV:Body>
  $in
  </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
*/
            Document envlDoc = newDocument();
            Element envlNode = 
                envlDoc.createElementNS(
                    "http://schemas.xmlsoap.org/soap/envelope/",
                    "SOAP-ENV:Envelope" );
            Element bodyNode =
                envlDoc.createElement( "SOAP-ENV:Body" );
            Node contents = envlDoc.importNode( in.getDocumentElement(), true );
            envlDoc.appendChild( envlNode );
            envlNode.appendChild( bodyNode );
            bodyNode.appendChild( contents );

            // create soappart from DOM
            DOMSource domSource = new DOMSource(envlDoc.getDocumentElement());
            soapPart.setContent(domSource);        

            // send
            SOAPConnectionFactory sf = SOAPConnectionFactory.newInstance();
            SOAPConnection conn = sf.createConnection();
            SOAPMessage response = conn.call(message, url);
            conn.close();

            // unwrap request, return the document
            //return unwrapResponse(resp);
            logger.info("XXX resp = " + response);

            SOAPBody respBody = response.getSOAPPart().getEnvelope().getBody();
            Document respDoc = newDocument();
            // XXX argh! SOAPBody isn't a DOM node!
            //respDoc.appendChild( respDoc.importNode( respBody, true ) );
            //return respDoc;
            return null; // XXX
        } catch (Exception e) { // XXX
            throw new TransportException("Cannot send message", e);
        }

    } //sendMessage()


    private Document newDocument() throws ParserConfigurationException {
        DocumentBuilderFactory builderfactory = 
            DocumentBuilderFactory.newInstance();
        builderfactory.setValidating(false);
        DocumentBuilder builder = builderfactory.newDocumentBuilder();
        return builder.newDocument();
    }
        
}
